package com.tiancikeji.zaoke.app.download.order;

import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.SheetUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.HttpRequestHandler;

import com.zaoke.web.bo.order.Order;
import com.zaoke.web.bo.order.OrderQuery;
import com.zaoke.web.bo.order.OrderQueryRes;
import com.zaoke.web.service.order.OrderService;

public class DownloadOrdersServlet implements HttpRequestHandler {
	
	private Logger logger = Logger.getLogger(DownloadOrdersServlet.class);

	/** 下载失败页面 */
	public static String DOWNLOAD_ERROR = "/systemBusy.html";

	private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

	@Autowired
	private OrderService orderService;
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		OutputStream out = null;
		try {
			
			response.setHeader("Content-Type", "application/msexcel");
			out = response.getOutputStream();
			HSSFWorkbook book = new HSSFWorkbook();

			OrderQuery query = new OrderQuery();
			query.setDrinkfoodid(NumberUtils.toLong(request.getParameter("drinkfoodid"), -1));
			query.setMainfoodid(NumberUtils.toLong(request.getParameter("mainfoodid"), -1));
			query.setPayway(NumberUtils.toInt(request.getParameter("payway"), -1));
			query.setState(NumberUtils.toInt(request.getParameter("state"), -1));
			query.setZoneid(NumberUtils.toLong(request.getParameter("zoneid"), -1));
			query.setUserid(NumberUtils.toLong(request.getParameter("userid"), -1));
			try{
				query.setPickdateF(format.parse(request.getParameter("pickdateF")));
			} catch(Throwable t){
//				t.printStackTrace();
			}
			try{
				query.setPickdateT(format.parse(request.getParameter("pickdateT")));
			} catch(Throwable t){
//				t.printStackTrace();
			}

			logger.info("reveived query : " + query);
			List<OrderQueryRes> orders = orderService.queryOrderInfo(query);
			if (orders != null && orders.size() > 0) {
				styles = new HashMap<String, HSSFCellStyle>();
				styles2 = new HashMap<Boolean, HSSFCellStyle>();
				
				String oriFileName = format.format(new Date()) + "早客订单";
				oriFileName = oriFileName.replaceAll("\\s+", ""); 
				oriFileName += ".xls";
				String agent = request.getHeader("USER-AGENT");
				if (null != agent && -1 != agent.indexOf("Firefox")) {
					response.setHeader("Content-disposition", "attachment;filename=" + new String(oriFileName.getBytes("utf-8"),"iso-8859-1"));
				} else {
					response.setHeader("Content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(oriFileName, "UTF-8"));
				}

				Map<String, Integer> all = new HashMap<String, Integer>();
				Map<String, Integer> topick0 = new HashMap<String, Integer>();
				Map<String, Integer> topick1 = new HashMap<String, Integer>();
				Map<String, Integer> picked2 = new HashMap<String, Integer>();
				Map<String, Integer> unpicked3 = new HashMap<String, Integer>();
				Map<String, Integer> unpicked4 = new HashMap<String, Integer>();
				Map<String, Integer> canceled5 = new HashMap<String, Integer>();
				
				int rowindex = 0;
				HSSFSheet sheet = book.createSheet(oriFileName);
				
				HSSFRow row = sheet.createRow(rowindex++);
				
				int columnIndex = 0;
				HSSFCell cell = row.createCell(columnIndex++);
				cell.setCellValue("订单编号");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("会员编号");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("会员昵称");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("取餐地点");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("金额");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("主食");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("饮品");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("支付方式");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("订单状态");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("预约取餐日期");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("订餐时间");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("实际取餐时间");
				setCellStyle(book, cell, true);

				for(OrderQueryRes data : orders){
					row = sheet.createRow(rowindex++);
					
					columnIndex = 0;
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getId());
					setCellStyle(book, cell, "TEXT");
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getUserid());
					setCellStyle(book, cell, "TEXT");
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getUsername());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getPickname());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(new DecimalFormat("0.00").format(data.getPrice()));
					setCellStyle(book, cell, floatformat);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getMainfood());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getDrinkfood());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getPayway());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getState());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(format.format(data.getBookdate()));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(data.getOrderdate());
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					if(data.getPickdate() != null)
						cell.setCellValue(data.getPickdate());
					else
						cell.setCellValue(StringUtils.EMPTY);
					setCellStyle(book, cell, false);
					
					int state = data.getStateInt();
					incr(all, topick0, topick1, picked2, unpicked3, unpicked4, canceled5, state, data.getMainfood());
					incr(all, topick0, topick1, picked2, unpicked3, unpicked4, canceled5, state, data.getDrinkfood());
				}
				
				for (int i = 0; i < 12; i++) {
					sheet.autoSizeColumn(i, true);
					double width = SheetUtil.getColumnWidth(sheet, i, true);

					if (width != -1) {
						width *= 512;
						int maxColumnWidth = 255 * 512; // The maximum column
														// width
						// for an individual cell is 255 characters
						if (width > maxColumnWidth) {
							width = maxColumnWidth;
						}
						sheet.setColumnWidth(i, (int) (width));
					}
				}
				
				rowindex = 0;
				sheet = book.createSheet("汇总");
				row = sheet.createRow(rowindex++);
				
				columnIndex = 0;
				cell = row.createCell(columnIndex++);
				cell.setCellValue("食品");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("未领取未支付");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("未领取已支付");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("已领取");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("已支付过期未取");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("未支付过期未取");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("已取消");
				setCellStyle(book, cell, true);
				cell = row.createCell(columnIndex++);
				cell.setCellValue("全部");
				setCellStyle(book, cell, true);
				
				for(String food : all.keySet()){
					row = sheet.createRow(rowindex++);
					
					columnIndex = 0;
					cell = row.createCell(columnIndex++);
					cell.setCellValue(food);
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(topick0, food));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(topick1, food));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(picked2, food));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(unpicked3, food));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(unpicked4, food));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(canceled5, food));
					setCellStyle(book, cell, false);
					cell = row.createCell(columnIndex++);
					cell.setCellValue(getCount(all, food));
					setCellStyle(book, cell, false);
				}
				
				for (int i = 0; i < 8; i++) {
					sheet.autoSizeColumn(i, true);
					double width = SheetUtil.getColumnWidth(sheet, i, true);

					if (width != -1) {
						width *= 512;
						int maxColumnWidth = 255 * 512; // The maximum column
														// width
						// for an individual cell is 255 characters
						if (width > maxColumnWidth) {
							width = maxColumnWidth;
						}
						sheet.setColumnWidth(i, (int) (width));
					}
				}
				
				/********** 收尾工作, 关闭close *************/
				book.write(out);
			} else{
				logger.warn("Nothing returned from db...");
				response.sendRedirect(request.getContextPath() + "/"
						+ DOWNLOAD_ERROR);
			}
		} catch (Exception e) {
			logger.warn("Download error. Reason:" + e, e);
			response.sendRedirect(request.getContextPath() + "/"
					+ DOWNLOAD_ERROR);
			return;
		} finally {
			try {
				if (out != null) {
					out.flush();
					out.close();
				}
			} catch (Exception e) {
				// 文件已下载完毕，不需要处理
			}
		}
	}

	private int getCount(Map<String, Integer> map, String food) {
		Integer count = map.get(food);
		if(count == null)
			return 0;
		else
			return count;
	}

	private void incr(Map<String, Integer> all, Map<String, Integer> topick0,
			Map<String, Integer> topick1, Map<String, Integer> picked2,
			Map<String, Integer> unpicked3, Map<String, Integer> unpicked4,
			Map<String, Integer> canceled5, int state, String food) {
		if(StringUtils.isNotBlank(food)){
			 incrCount(all, food);
			 
			 if(state == Order.STATE_UNPAID)
				 incrCount(topick0, food);
			 else if(state == Order.STATE_PAID)
				 incrCount(topick1, food);
			 else if(state == Order.STATE_TOKEN)
				 incrCount(picked2, food);
			 else if(state == Order.STATE_UNPAID_EXPIRE)
				 incrCount(unpicked3, food);
			 else if(state == Order.STATE_PAID_EXPIRE)
				 incrCount(unpicked4, food);
			 else if(state == Order.STATE_CANCEL)
				 incrCount(canceled5, food);
		}
	}

	private void incrCount(Map<String, Integer> map, String food) {
		Integer c = map.get(food);
		 if(c == null)
			 c = 0;
		 
		 map.put(food, ++ c);
	}
	
	private String floatformat = "0.00";
	
	private Map<String, HSSFCellStyle> styles = new HashMap<String, HSSFCellStyle>();
	
	private Map<Boolean, HSSFCellStyle> styles2 = new HashMap<Boolean, HSSFCellStyle>();

	private void setCellStyle(HSSFWorkbook book, HSSFCell cell, String format) {
		HSSFCellStyle style = styles.get(format);
		if(style == null){
			HSSFDataFormat df = book.createDataFormat();
			style = book.createCellStyle();
			style.setAlignment(CellStyle.ALIGN_CENTER);
			style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
			style.setWrapText(false);
			HSSFFont font = book.createFont();
			font.setFontName("微软雅黑");
			font.setFontHeightInPoints((short) 10);
			style.setFont(font);
			style.setFillBackgroundColor(HSSFCellStyle.THICK_VERT_BANDS);
			style.setDataFormat(df.getFormat(format));
			styles.put(format, style);
		}
		
		cell.setCellStyle(style);
	}

	private void setCellStyle(HSSFWorkbook book, HSSFCell cell, boolean bold) {
		HSSFCellStyle style = styles2.get(bold);
		if(style == null){
			style = book.createCellStyle();
			style.setAlignment(CellStyle.ALIGN_CENTER);
			style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
			style.setWrapText(false);
			HSSFFont font = book.createFont();
			font.setFontName("微软雅黑");
			font.setFontHeightInPoints((short) 10);
			if (bold) {
				font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
			}
			style.setFont(font);
			style.setFillBackgroundColor(HSSFCellStyle.THICK_VERT_BANDS);
			styles2.put(bold, style);
		}
		cell.setCellStyle(style);
	}

	public void handleRequest(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		doGet(req, res);

	}

	public OrderService getOrderService() {
		return orderService;
	}

	public void setOrderService(OrderService orderService) {
		this.orderService = orderService;
	}

}
